home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / less.arc / LESS.PT2 < prev   
Text File  |  1986-08-13  |  67KB  |  2,990 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    makefile.sys5
  7. #    makefile.xen
  8. #    mkfuncs.awk
  9. #    n10-diff
  10. #    option.c
  11. #    output.c
  12. #    pager_patch.c
  13. #    position.c
  14. #    position.h
  15. #    prim.c
  16. #    prompt.c
  17. #    screen.c
  18. #    signal.c
  19. #    ttyin.c
  20. #    version.c
  21. export PATH; PATH=/bin:/usr/bin:$PATH
  22. if test -f 'makefile.sys5'
  23. then
  24.     echo shar: "will not over-write existing file 'makefile.sys5'"
  25. else
  26. cat << \SHAR_EOF > 'makefile.sys5'
  27. # Makefile for "less"
  28. #
  29. # Invoked as:
  30. #    make all
  31. #   or    make install
  32. # Plain "make" is equivalent to "make all".
  33. #
  34. # If you add or delete functions, remake funcs.h by doing:
  35. #    make newfuncs
  36. # This depends on the coding convention of function headers looking like:
  37. #    " \t public <function-type> \n <function-name> ( ... ) "
  38. #
  39. # Also provided:
  40. #    make lint    # Runs "lint" on all the sources.
  41. #    make clean    # Removes "less" and the .o files.
  42. #    make clobber    # Pretty much the same as make "clean".
  43. #
  44. #    make pager_patch        # makes PAGER environment variable
  45. #    make install_pager_patch    # catcher and installs it (see below)
  46.  
  47.  
  48. ##########################################################################
  49. # System-specific parameters
  50. ##########################################################################
  51.  
  52. # Define XENIX if running under XENIX 3.0
  53. XENIX = 0
  54.  
  55. # VOID is 1 if your C compiler supports the "void" type,
  56. # 0 if it does not.
  57. VOID = 1
  58.  
  59. # off_t is the type which lseek() returns.
  60. # It is also the type of lseek()'s second argument.
  61. off_t = long
  62.  
  63. # TERMIO is 1 if your system has /usr/include/termio.h.
  64. # This is normally the case for System 5.
  65. # If TERMIO is 0 your system must have /usr/include/sgtty.h.
  66. # This is normally the case for BSD.
  67. TERMIO = 1
  68.  
  69. # SIGSETMASK is 1 if your system has the sigsetmask() call.
  70. # This is normally the case only for BSD 4.2,
  71. # not for BSD 4.1 or System 5.
  72. SIGSETMASK = 0
  73.  
  74.  
  75. ##########################################################################
  76. # Optional and semi-optional features
  77. ##########################################################################
  78.  
  79. # REGCMP is 1 if your system has the regcmp() function.
  80. # This is normally the case for System 5.
  81. # RECOMP is 1 if your system has the re_comp() function.
  82. # This is normally the case for BSD.
  83. # If neither is 1, pattern matching is supported, but without metacharacters.
  84. REGCMP = 1
  85. RECOMP = 0
  86.  
  87. # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
  88. # (This is possible only if your system supplies the system() function.)
  89. SHELL_ESCAPE = 0
  90.  
  91. # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
  92. # (This is possible only if your system supplies the system() function.)
  93. # EDIT_PGM is the name of the (default) editor to be invoked.
  94. EDITOR = 0
  95. EDIT_PGM = /usr/ucb/vi
  96.  
  97. # parameters to "make install_pager_patch".  OLD_PAGER will be moved to
  98. # OLD_PAGER_NEW_LOCATION and pager_patch (in this directory) will be installed
  99. # as OLD_PAGER.  This patch will allow you to set the environment variable
  100. # PAGER to specify your personal pager preference (is this a security hole?)
  101. OLD_PAGER = /usr/ucb/more
  102. OLD_PAGER_NEW_LOCATION = /usr/ucb/More
  103.  
  104. # ONLY_RETURN is 1 if you want RETURN to be the only input which
  105. # will continue past an error message.
  106. # Otherwise, any key will continue past an error message.
  107. ONLY_RETURN = 0
  108.  
  109.  
  110. ##########################################################################
  111. # Compilation environment.
  112. ##########################################################################
  113.  
  114. # LIBS is the list of libraries needed.
  115. LIBS = -lcurses -lPW
  116.  
  117. # INSTALL_LESS is a list of the public versions of less.
  118. # INSTALL_MAN is a list of the public versions of the manual page.
  119. INSTALL_LESS =    /usr/lbin/less
  120. INSTALL_MAN =    /usr/man/manl/less.l
  121.  
  122. # OPTIM is passed to the compiler and the loader.
  123. # It is normally "-O" but may be, for example, "-g".
  124. OPTIM = -O
  125.  
  126.  
  127. ##########################################################################
  128. # Files
  129. ##########################################################################
  130.  
  131. SRC1 =    main.c option.c prim.c 
  132. SRC2 =    ch.c position.c input.c output.c screen.c \
  133.     prompt.c line.c signal.c help.c ttyin.c command.c version.c
  134. SRC =    $(SRC1) $(SRC2)
  135. OBJ =    main.o option.o prim.o ch.o position.o input.o output.o screen.o \
  136.     prompt.o line.o signal.o help.o ttyin.o command.o version.o
  137.  
  138.  
  139. ##########################################################################
  140. # Rules
  141. ##########################################################################
  142.  
  143. DEFS =    "-DTERMIO=$(TERMIO)" \
  144.     "-DSIGSETMASK=$(SIGSETMASK)" \
  145.     "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
  146.     "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
  147.     "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
  148.     "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
  149.     "-DONLY_RETURN=$(ONLY_RETURN)" \
  150.     "-DXENIX=$(XENIX)" \
  151.     "-DOLD_PAGER_NEW_LOCATION=\"$(OLD_PAGER_NEW_LOCATION)\""
  152.  
  153. CFLAGS = $(OPTIM) $(DEFS)
  154.  
  155.  
  156. all: less
  157.  
  158. less: $(OBJ)
  159.     cc $(OPTIM) -o less $(OBJ) $(LIBS)
  160.  
  161. install: install_man install_less
  162.  
  163. install_man: less.l
  164.     for f in $(INSTALL_MAN); do  rm -f $$f; cp less.l $$f;  done
  165.     touch install_man
  166.     
  167. install_less: less
  168.     for f in $(INSTALL_LESS); do  rm -f $$f; cp less $$f;  done
  169.     touch install_less
  170.  
  171. pager_patch: pager_patch.c
  172.     cc $(CFLAGS) -s -o pager_patch pager_patch.c
  173.  
  174. install_pager_patch: pager_patch
  175.     if [ -s $(OLD_PAGER) -a ! -s $(OLD_PAGER_NEW_LOCATION) ]; then \
  176.         mv $(OLD_PAGER) $(OLD_PAGER_NEW_LOCATION); \
  177.         cp pager_patch $(OLD_PAGER); \
  178.     fi
  179.     touch install_pager_patch
  180.  
  181. $(OBJ): less.h funcs.h
  182.  
  183. lint:
  184.     lint -hp $(DEFS) $(SRC)
  185.  
  186. newfuncs:
  187.     mv funcs.h funcs.h.OLD
  188.     awk -f mkfuncs.awk $(SRC) >funcs.h
  189.  
  190. clean:
  191.     rm -f $(OBJ) less pager_patch
  192.  
  193. clobber:
  194.     rm -f *.o less pager_patch install_less install_man install_pager_patch
  195.  
  196. shar:
  197.     shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
  198.     shar -v $(SRC2) pager_patch.c > less.shar.b
  199. SHAR_EOF
  200. fi
  201. if test -f 'makefile.xen'
  202. then
  203.     echo shar: "will not over-write existing file 'makefile.xen'"
  204. else
  205. cat << \SHAR_EOF > 'makefile.xen'
  206. # Makefile for "less"
  207. #
  208. # Invoked as:
  209. #    make all
  210. #   or    make install
  211. # Plain "make" is equivalent to "make all".
  212. #
  213. # If you add or delete functions, remake funcs.h by doing:
  214. #    make newfuncs
  215. # This depends on the coding convention of function headers looking like:
  216. #    " \t public <function-type> \n <function-name> ( ... ) "
  217. #
  218. # Also provided:
  219. #    make lint    # Runs "lint" on all the sources.
  220. #    make clean    # Removes "less" and the .o files.
  221. #    make clobber    # Pretty much the same as make "clean".
  222. #
  223. #    make pager_patch        # makes PAGER environment variable
  224. #    make install_pager_patch    # catcher and installs it (see below)
  225.  
  226.  
  227. ##########################################################################
  228. # System-specific parameters
  229. ##########################################################################
  230.  
  231. # Define XENIX if running under XENIX 3.0
  232. XENIX = 1
  233.  
  234. # VOID is 1 if your C compiler supports the "void" type,
  235. # 0 if it does not.
  236. VOID = 1
  237.  
  238. # off_t is the type which lseek() returns.
  239. # It is also the type of lseek()'s second argument.
  240. off_t = long
  241.  
  242. # TERMIO is 1 if your system has /usr/include/termio.h.
  243. # This is normally the case for System 5.
  244. # If TERMIO is 0 your system must have /usr/include/sgtty.h.
  245. # This is normally the case for BSD.
  246. TERMIO = 1
  247.  
  248. # SIGSETMASK is 1 if your system has the sigsetmask() call.
  249. # This is normally the case only for BSD 4.2,
  250. # not for BSD 4.1 or System 5.
  251. SIGSETMASK = 0
  252.  
  253.  
  254. ##########################################################################
  255. # Optional and semi-optional features
  256. ##########################################################################
  257.  
  258. # REGCMP is 1 if your system has the regcmp() function.
  259. # This is normally the case for System 5.
  260. # RECOMP is 1 if your system has the re_comp() function.
  261. # This is normally the case for BSD.
  262. # If neither is 1, pattern matching is supported, but without metacharacters.
  263. REGCMP = 1
  264. RECOMP = 0
  265.  
  266. # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
  267. # (This is possible only if your system supplies the system() function.)
  268. SHELL_ESCAPE = 0
  269.  
  270. # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
  271. # (This is possible only if your system supplies the system() function.)
  272. # EDIT_PGM is the name of the (default) editor to be invoked.
  273. EDITOR = 0
  274. EDIT_PGM = /usr/ucb/vi
  275.  
  276. # parameters to "make install_pager_patch".  OLD_PAGER will be moved to
  277. # OLD_PAGER_NEW_LOCATION and pager_patch (in this directory) will be installed
  278. # as OLD_PAGER.  This patch will allow you to set the environment variable
  279. # PAGER to specify your personal pager preference (is this a security hole?)
  280. OLD_PAGER = /usr/ucb/more
  281. OLD_PAGER_NEW_LOCATION = /usr/ucb/More
  282.  
  283. # ONLY_RETURN is 1 if you want RETURN to be the only input which
  284. # will continue past an error message.
  285. # Otherwise, any key will continue past an error message.
  286. ONLY_RETURN = 0
  287.  
  288.  
  289. ##########################################################################
  290. # Compilation environment.
  291. ##########################################################################
  292.  
  293. # LIBS is the list of libraries needed.
  294. LIBS = -lcurses -ltermlib
  295.  
  296. # INSTALL_LESS is a list of the public versions of less.
  297. # INSTALL_MAN is a list of the public versions of the manual page.
  298. INSTALL_LESS =    /usr/lbin/less
  299. INSTALL_MAN =    /usr/man/manl/less.l
  300.  
  301. # OPTIM is passed to the compiler and the loader.
  302. # It is normally "-O" but may be, for example, "-g".
  303. OPTIM = -O
  304.  
  305.  
  306. ##########################################################################
  307. # Files
  308. ##########################################################################
  309.  
  310. SRC1 =    main.c option.c prim.c 
  311. SRC2 =    ch.c position.c input.c output.c screen.c \
  312.     prompt.c line.c signal.c help.c ttyin.c command.c version.c
  313. SRC =    $(SRC1) $(SRC2)
  314. OBJ =    main.o option.o prim.o ch.o position.o input.o output.o screen.o \
  315.     prompt.o line.o signal.o help.o ttyin.o command.o version.o
  316.  
  317.  
  318. ##########################################################################
  319. # Rules
  320. ##########################################################################
  321.  
  322. DEFS =    "-DTERMIO=$(TERMIO)" \
  323.     "-DSIGSETMASK=$(SIGSETMASK)" \
  324.     "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
  325.     "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
  326.     "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
  327.     "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
  328.     "-DONLY_RETURN=$(ONLY_RETURN)" \
  329.     "-DXENIX=$(XENIX)" \
  330.     "-DOLD_PAGER_NEW_LOCATION=\"$(OLD_PAGER_NEW_LOCATION)\""
  331.  
  332. CFLAGS = $(OPTIM) $(DEFS)
  333.  
  334.  
  335. all: less
  336.  
  337. less: $(OBJ)
  338.     cc $(OPTIM) -o less $(OBJ) $(LIBS)
  339.  
  340. install: install_man install_less
  341.  
  342. install_man: less.l
  343.     for f in $(INSTALL_MAN); do  rm -f $$f; cp less.l $$f;  done
  344.     touch install_man
  345.     
  346. install_less: less
  347.     for f in $(INSTALL_LESS); do  rm -f $$f; cp less $$f;  done
  348.     touch install_less
  349.  
  350. pager_patch: pager_patch.c
  351.     cc $(CFLAGS) -s -o pager_patch pager_patch.c
  352.  
  353. install_pager_patch: pager_patch
  354.     if [ -s $(OLD_PAGER) -a ! -s $(OLD_PAGER_NEW_LOCATION) ]; then \
  355.         mv $(OLD_PAGER) $(OLD_PAGER_NEW_LOCATION); \
  356.         cp pager_patch $(OLD_PAGER); \
  357.     fi
  358.     touch install_pager_patch
  359.  
  360. $(OBJ): less.h funcs.h
  361.  
  362. lint:
  363.     lint -hp $(DEFS) $(SRC)
  364.  
  365. newfuncs:
  366.     mv funcs.h funcs.h.OLD
  367.     awk -f mkfuncs.awk $(SRC) >funcs.h
  368.  
  369. clean:
  370.     rm -f $(OBJ) less pager_patch
  371.  
  372. clobber:
  373.     rm -f *.o less pager_patch install_less install_man install_pager_patch
  374.  
  375. shar:
  376.     shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
  377.     shar -v $(SRC2) pager_patch.c > less.shar.b
  378. SHAR_EOF
  379. fi
  380. if test -f 'mkfuncs.awk'
  381. then
  382.     echo shar: "will not over-write existing file 'mkfuncs.awk'"
  383. else
  384. cat << \SHAR_EOF > 'mkfuncs.awk'
  385. BEGIN { FS="("; state = 0 }
  386.  
  387. /^    public/ { ftype = $0; state = 1 }
  388.  
  389. { if (state == 1)
  390.     state = 2
  391.   else if (state == 2)
  392.     { print ftype,$1,"();"; state = 0 }
  393. }
  394. SHAR_EOF
  395. fi
  396. if test -f 'n10-diff'
  397. then
  398.     echo shar: "will not over-write existing file 'n10-diff'"
  399. else
  400. cat << \SHAR_EOF > 'n10-diff'
  401. *** n10-old.c    Sun May  4 01:45:06 1986
  402. --- n10.c    Mon Jul 14 12:27:54 1986
  403. ***************
  404. *** 137,151
  405.       if(*codep && (esc || lead))move();
  406.       esct += w;
  407.       if(i&074000)xfont = (i>>9) & 03;
  408. !     if(*t.bdon & 0377){
  409. !         if(!bdmode && (xfont == 2)){
  410. !             oputs(t.bdon);
  411. !             bdmode++;
  412. !         }
  413. !         if(bdmode && (xfont != 2)){
  414. !             oputs(t.bdoff);
  415. !             bdmode = 0;
  416. !         }
  417.       }
  418.       if(xfont == ulfont){
  419.           for(k=w/t.Char;k>0;k--)oput('_');
  420.  
  421. --- 137,145 -----
  422.       if(*codep && (esc || lead))move();
  423.       esct += w;
  424.       if(i&074000)xfont = (i>>9) & 03;
  425. !     if(!bdmode && (xfont == 2)){
  426. !         if(*t.bdon & 0377)oputs(t.bdon);
  427. !         bdmode++;
  428.       }
  429.       if(bdmode && (xfont != 2)){
  430.           if(*t.bdoff & 0377)oputs(t.bdoff);
  431. ***************
  432. *** 147,152
  433.               bdmode = 0;
  434.           }
  435.       }
  436.       if(xfont == ulfont){
  437.           for(k=w/t.Char;k>0;k--)oput('_');
  438.           for(k=w/t.Char;k>0;k--)oput('\b');
  439.  
  440. --- 141,150 -----
  441.           if(*t.bdon & 0377)oputs(t.bdon);
  442.           bdmode++;
  443.       }
  444. +     if(bdmode && (xfont != 2)){
  445. +         if(*t.bdoff & 0377)oputs(t.bdoff);
  446. +         bdmode = 0;
  447. +     }
  448.       if(xfont == ulfont){
  449.           for(k=w/t.Char;k>0;k--)oput('_');
  450.           for(k=w/t.Char;k>0;k--)oput('\b');
  451. ***************
  452. *** 158,163
  453.               oput(' ');
  454.           }else{
  455.               if(plotmode)oputs(t.plotoff);
  456.               *obufp++ = *codep++;
  457.               if(obufp == (obuf + OBUFSZ + ascii - 1))flusho();
  458.   /*            oput(*codep++);*/
  459.  
  460. --- 156,162 -----
  461.               oput(' ');
  462.           }else{
  463.               if(plotmode)oputs(t.plotoff);
  464. +             if(obufp >= (obuf + OBUFSZ + ascii - 1 - (bdmode?3:1)))flusho();
  465.               *obufp++ = *codep++;
  466.               if(bdmode && !*t.bdon){
  467.                   *obufp++ = '\b';
  468. ***************
  469. *** 159,165
  470.           }else{
  471.               if(plotmode)oputs(t.plotoff);
  472.               *obufp++ = *codep++;
  473. !             if(obufp == (obuf + OBUFSZ + ascii - 1))flusho();
  474.   /*            oput(*codep++);*/
  475.           }
  476.       }
  477.  
  478. --- 158,167 -----
  479.               if(plotmode)oputs(t.plotoff);
  480.               if(obufp >= (obuf + OBUFSZ + ascii - 1 - (bdmode?3:1)))flusho();
  481.               *obufp++ = *codep++;
  482. !             if(bdmode && !*t.bdon){
  483. !                 *obufp++ = '\b';
  484. !                 *obufp++ = codep[-1];
  485. !             }
  486.   /*            oput(*codep++);*/
  487.           }
  488.       }
  489. SHAR_EOF
  490. fi
  491. if test -f 'option.c'
  492. then
  493.     echo shar: "will not over-write existing file 'option.c'"
  494. else
  495. cat << \SHAR_EOF > 'option.c'
  496. /*
  497.  * Process command line options.
  498.  * Each option is a single letter which controls a program variable.
  499.  * The options have defaults which may be changed via
  500.  * the command line option, or toggled via the "-" command.
  501.  */
  502.  
  503. #include "less.h"
  504.  
  505. #define    toupper(c)    ((c)-'a'+'A')
  506.  
  507. /*
  508.  * Types of options.
  509.  */
  510. #define    BOOL        01    /* Boolean option: 0 or 1 */
  511. #define    TRIPLE        02    /* Triple-valued option: 0, 1 or 2 */
  512. #define    NUMBER        04    /* Numeric option */
  513. #define    NO_TOGGLE    0100    /* Option cannot be toggled with "-" cmd */
  514.  
  515. /*
  516.  * Variables controlled by command line options.
  517.  */
  518. public int p_nbufs, f_nbufs;    /* Number of buffers.  There are two values,
  519.                    one used for input from a pipe and 
  520.                    the other for input from a file. */
  521. public int clean_data;        /* Can we assume the data is "clean"? 
  522.                    (That is, free of nulls, etc) */
  523. public int quiet;        /* Should we suppress the audible bell? */
  524. public int top_search;        /* Should forward searches start at the top 
  525.                    of the screen? (alternative is bottom) */
  526. public int top_scroll;        /* Repaint screen from top?
  527.                    (alternative is scroll from bottom) */
  528. public int pr_type;        /* Type of prompt (short, medium, long) */
  529. public int bs_mode;        /* How to process backspaces */
  530. public int know_dumb;        /* Don't complain about dumb terminals */
  531. public int quit_at_eof;        /* Quit after hitting end of file twice */
  532. public int squeeze;        /* Squeeze multiple blank lines into one */
  533. public int tabstop;        /* Tab settings */
  534. public int back_scroll;        /* Repaint screen on backwards movement */
  535. public int twiddle;        /* Display "~" for lines after EOF */
  536.  
  537. extern int nbufs;
  538. extern int sc_window;
  539. extern char *first_cmd;
  540. extern char *every_first_cmd;
  541.  
  542. #define    DEF_F_NBUFS    5    /* Default for f_nbufs */
  543. #define    DEF_P_NBUFS    12    /* Default for p_nbufs */
  544.  
  545. static struct option
  546. {
  547.     char oletter;        /* The controlling letter (a-z) */
  548.     char otype;        /* Type of the option */
  549.     int odefault;        /* Default value */
  550.     int *ovar;        /* Pointer to the associated variable */
  551.     char *odesc[3];        /* Description of each value */
  552. } option[] =
  553. {
  554.     { 'c', BOOL, 0, &clean_data,
  555.         { "Don't assume data is clean",
  556.           "Assume data is clean",
  557.           NULL
  558.         }
  559.     },
  560.     { 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
  561.         { NULL, NULL, NULL}
  562.     },
  563.     { 'e', BOOL, 0, &quit_at_eof,
  564.         { "Don't quit at end-of-file",
  565.           "Quit at end-of-file",
  566.           NULL
  567.         }
  568.     },
  569.     { 'h', NUMBER, -1, &back_scroll,
  570.         { "Backwards scroll limit is %d lines",
  571.           NULL, NULL
  572.         }
  573.     },
  574.     { 'p', BOOL, 0, &top_scroll,
  575.         { "Repaint by scrolling from bottom of screen",
  576.           "Repaint by painting from top of screen",
  577.           NULL
  578.         }
  579.     },
  580.     { 'x', NUMBER, 8, &tabstop,
  581.         { "Tab stops every %d spaces", 
  582.           NULL, NULL 
  583.         }
  584.     },
  585.     { 's', BOOL, 0, &squeeze,
  586.         { "Don't squeeze multiple blank lines",
  587.           "Squeeze multiple blank lines",
  588.           NULL
  589.         }
  590.     },
  591.     { 't', BOOL, 1, &top_search,
  592.         { "Forward search starts from bottom of screen",
  593.           "Forward search starts from top of screen",
  594.           NULL
  595.         }
  596.     },
  597.     { 'w', BOOL, 1, &twiddle,
  598.         { "Display nothing for lines after end-of-file",
  599.           "Display ~ for lines after end-of-file",
  600.           NULL
  601.         }
  602.     },
  603.     { 'm', TRIPLE, 0, &pr_type,
  604.         { "Prompt with a colon",
  605.           "Prompt with a message",
  606.           "Prompt with a verbose message"
  607.         }
  608.     },
  609.     { 'q', TRIPLE, 0, &quiet,
  610.         { "Ring the bell for errors AND at eof/bof",
  611.           "Ring the bell for errors but not at eof/bof",
  612.           "Never ring the bell"
  613.         }
  614.     },
  615.     { 'u', TRIPLE, 0, &bs_mode,
  616.         { "Underlined text displayed in underline mode",
  617.           "All backspaces cause overstrike",
  618.           "Backspaces print as ^H"
  619.         }
  620.     },
  621.     { 'z', NUMBER, 24, &sc_window,
  622.         { "Scroll window size is %d lines",
  623.           NULL, NULL
  624.         }
  625.     },
  626.     { '\0' }
  627. };
  628.  
  629. public char all_options[64];    /* List of all valid options */
  630.  
  631. /*
  632.  * Initialize each option to its default value.
  633.  */
  634.     public void
  635. init_option()
  636. {
  637.     register struct option *o;
  638.     register char *p;
  639.  
  640.     /*
  641.      * First do special cases, not in option table.
  642.      */
  643.     first_cmd = every_first_cmd = NULL;
  644.     f_nbufs = DEF_F_NBUFS;        /* -bf */
  645.     p_nbufs = DEF_P_NBUFS;        /* -bp */
  646.  
  647.     p = all_options;
  648.     *p++ = 'b';
  649.  
  650.     for (o = option;  o->oletter != '\0';  o++)
  651.     {
  652.         /*
  653.          * Set each variable to its default.
  654.          * Also make a list of all options, in "all_options".
  655.          */
  656.         *(o->ovar) = o->odefault;
  657.         *p++ = o->oletter;
  658.         if (o->otype & TRIPLE)
  659.             *p++ = toupper(o->oletter);
  660.     }
  661.     *p = '\0';
  662. }
  663.  
  664. /*
  665.  * Toggle command line flags from within the program.
  666.  * Used by the "-" command.
  667.  */
  668.     public void
  669. toggle_option(c)
  670.     int c;
  671. {
  672.     register struct option *o;
  673.     char message[100];
  674.     char buf[5];
  675.  
  676.     /*
  677.      * First check for special cases not handled by the option table.
  678.      */
  679.     switch (c)
  680.     {
  681.     case 'b':
  682.         sprintf(message, "%d buffers", nbufs);
  683.         error(message);
  684.         return;
  685.     }
  686.  
  687.  
  688.     for (o = option;  o->oletter != '\0';  o++)
  689.     {
  690.         if ((o->otype & BOOL) && (o->oletter == c) &&
  691.             (o->otype & NO_TOGGLE) == 0)
  692.         {
  693.             /*
  694.              * Boolean option: 
  695.              * just toggle it.
  696.              */
  697.             *(o->ovar) = ! *(o->ovar);
  698.             error(o->odesc[*(o->ovar)]);
  699.             return;
  700.         } else if ((o->otype & TRIPLE) && (o->oletter == c) &&
  701.             (o->otype & NO_TOGGLE) == 0)
  702.         {
  703.             /*
  704.              * Triple-valued option with lower case letter:
  705.              * make it 1 unless already 1, then make it 0.
  706.              */
  707.             *(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
  708.             error(o->odesc[*(o->ovar)]);
  709.             return;
  710.         } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c) &&
  711.             (o->otype & NO_TOGGLE) == 0)
  712.         {
  713.             /*
  714.              * Triple-valued option with upper case letter:
  715.              * make it 2 unless already 2, then make it 0.
  716.              */
  717.             *(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
  718.             error(o->odesc[*(o->ovar)]);
  719.             return;
  720.         } else if ((o->otype & NUMBER) && (o->oletter == c) &&
  721.             (o->otype & NO_TOGGLE) == 0)
  722.         {
  723.             sprintf(message, o->odesc[0], *(o->ovar));
  724.             error(message);
  725.             return;
  726.         }
  727.     }
  728.  
  729.     if (control_char(c))
  730.         sprintf(buf, "^%c", carat_char(c));
  731.     else
  732.         sprintf(buf, "%c", c);
  733.     sprintf(message, "\"-%s\": no such flag.  Use one of \"%s\"", 
  734.         buf, all_options);
  735.     error(message);
  736. }
  737.  
  738. /*
  739.  * Scan an argument (either from command line or from LESS environment 
  740.  * variable) and process it.
  741.  */
  742.     public void
  743. scan_option(s)
  744.     char *s;
  745. {
  746.     register struct option *o;
  747.     register int c;
  748.  
  749.     if (s == NULL)
  750.         return;
  751.  
  752.     next:
  753.     if (*s == '\0')
  754.         return;
  755.     switch (c = *s++)
  756.     {
  757.     case '-':
  758.     case ' ':
  759.     case '\t':
  760.         goto next;
  761.     case '+':
  762.         if (*s == '+')
  763.             every_first_cmd = ++s;
  764.         first_cmd = s;
  765.         return;
  766.     case 'b':
  767.         switch (*s)
  768.         {
  769.         case 'f':
  770.             s++;
  771.             f_nbufs = getnum(&s, 'b');
  772.             break;
  773.         case 'p':
  774.             s++;
  775.             p_nbufs = getnum(&s, 'b');
  776.             break;
  777.         default:
  778.             f_nbufs = p_nbufs = getnum(&s, 'b');
  779.             break;
  780.         }
  781.         goto next;
  782.     case '0':  case '1':  case '2':  case '3':  case '4':
  783.     case '5':  case '6':  case '7':  case '8':  case '9':
  784.         {
  785.             /*
  786.              * Handle special "more" compatibility form "-number"
  787.              * to set the scrolling window size.
  788.              */
  789.             s--;
  790.             sc_window = getnum(&s, '-');
  791.             goto next;
  792.         }
  793.     }
  794.  
  795.     for (o = option;  o->oletter != '\0';  o++)
  796.     {
  797.         if ((o->otype & BOOL) && (o->oletter == c))
  798.         {
  799.             *(o->ovar) = ! o->odefault;
  800.             goto next;
  801.         } else if ((o->otype & TRIPLE) && (o->oletter == c))
  802.         {
  803.             *(o->ovar) = (o->odefault == 1) ? 0 : 1;
  804.             goto next;
  805.         } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
  806.         {
  807.             *(o->ovar) = (o->odefault == 2) ? 0 : 2;
  808.             goto next;
  809.         } else if ((o->otype & NUMBER) && (o->oletter == c))
  810.         {
  811.             *(o->ovar) = getnum(&s, c);
  812.             goto next;
  813.         }
  814.     }
  815.  
  816.     printf("\"-%c\": invalid flag\n", c);
  817.     exit(1);
  818. }
  819.  
  820. /*
  821.  * Translate a string into a number.
  822.  * Like atoi(), but takes a pointer to a char *, and updates
  823.  * the char * to point after the translated number.
  824.  */
  825.     static int
  826. getnum(sp, c)
  827.     char **sp;
  828.     int c;
  829. {
  830.     register char *s;
  831.     register int n;
  832.  
  833.     s = *sp;
  834.     if (*s < '0' || *s > '9')
  835.     {
  836.         printf("number is required after -%c\n", c);
  837.         exit(1);
  838.     }
  839.  
  840.     n = 0;
  841.     while (*s >= '0' && *s <= '9')
  842.         n = 10 * n + *s++ - '0';
  843.     *sp = s;
  844.     return (n);
  845. }
  846. SHAR_EOF
  847. fi
  848. if test -f 'output.c'
  849. then
  850.     echo shar: "will not over-write existing file 'output.c'"
  851. else
  852. cat << \SHAR_EOF > 'output.c'
  853. /*
  854.  * High level routines dealing with the output to the screen.
  855.  */
  856.  
  857. #include "less.h"
  858.  
  859. extern int sigs;
  860. extern int sc_width, sc_height;
  861. extern int bo_width, be_width;
  862. extern int ul_width, ue_width;
  863. extern int so_width, se_width;
  864. extern int tabstop;
  865. extern int twiddle;
  866. extern char *line;
  867. extern char *first_cmd;
  868.  
  869. /*
  870.  * Display the line which is in the line buffer.
  871.  */
  872.     public void
  873. put_line()
  874. {
  875.     register char *p;
  876.     register int c;
  877.     register int column;
  878.     extern int auto_wrap, ignaw;
  879.  
  880.     if (sigs)
  881.         /*
  882.          * Don't output if a signal is pending.
  883.          */
  884.         return;
  885.  
  886.     if (line == NULL)
  887.         line = (twiddle) ? "~" : "";
  888.  
  889.     column = 0;
  890.     for (p = line;  *p != '\0';  p++)
  891.     {
  892.         switch (c = *p)
  893.         {
  894.         case UL_CHAR:
  895.             ul_enter();
  896.             column += ul_width;
  897.             break;
  898.         case UE_CHAR:
  899.             ul_exit();
  900.             column += ue_width;
  901.             break;
  902.         case BO_CHAR:
  903.             bo_enter();
  904.             column += bo_width;
  905.             break;
  906.         case BE_CHAR:
  907.             bo_exit();
  908.             column += be_width;
  909.             break;
  910.         case '\t':
  911.             do
  912.             {
  913.                 putc(' ');
  914.                 column++;
  915.             } while ((column % tabstop) != 0);
  916.             break;
  917.         case '\b':
  918.             putbs();
  919.             column--;
  920.             break;
  921.         default:
  922.             if (c & 0200)
  923.             {
  924.                 putc('^');
  925.                 putc(c & 0177);
  926.                 column += 2;
  927.             } else
  928.             {
  929.                 putc(c);
  930.                 column++;
  931.             }
  932.         }
  933.     }
  934.     if (column < sc_width || !auto_wrap || ignaw)
  935.         putc('\n');
  936. }
  937.  
  938. /*
  939.  * Is a given character a "control" character?
  940.  * {{ ASCII DEPENDENT }}
  941.  */
  942.     public int
  943. control_char(c)
  944.     int c;
  945. {
  946.     return (c < ' ' || c == '\177');
  947. }
  948.  
  949. /*
  950.  * Return the printable character used to identify a control character
  951.  * (printed after a carat; e.g. '\3' => "^C").
  952.  * {{ ASCII DEPENDENT }}
  953.  */
  954.     public int
  955. carat_char(c)
  956.     int c;
  957. {
  958.     return ((c == '\177') ? '?' : (c | 0100));
  959. }
  960.  
  961.  
  962. static char obuf[1024];
  963. static char *ob = obuf;
  964.  
  965. /*
  966.  * Flush buffered output.
  967.  */
  968.     public void
  969. flush()
  970. {
  971.     write(1, obuf, ob-obuf);
  972.     ob = obuf;
  973. }
  974.  
  975. /*
  976.  * Discard buffered output.
  977.  */
  978.     public void
  979. dropout()
  980. {
  981.     ob = obuf;
  982. }
  983.  
  984. /*
  985.  * Output a character.
  986.  */
  987.     public void
  988. putc(c)
  989.     int c;
  990. {
  991.     if (ob >= &obuf[sizeof(obuf)])
  992.         flush();
  993.     *ob++ = c;
  994. }
  995.  
  996. /*
  997.  * Output a string.
  998.  */
  999.     public void
  1000. puts(s)
  1001.     register char *s;
  1002. {
  1003.     while (*s != '\0')
  1004.         putc(*s++);
  1005. }
  1006.  
  1007. /*
  1008.  * Output a message in the lower left corner of the screen
  1009.  * and wait for carriage return.
  1010.  */
  1011.  
  1012. static char return_to_continue[] = "  (press RETURN)";
  1013.  
  1014.     public void
  1015. error(s)
  1016.     char *s;
  1017. {
  1018.     register int c;
  1019.     static char buf[2];
  1020.  
  1021.     lower_left();
  1022.     clear_eol();
  1023.     so_enter();
  1024.     puts(s);
  1025.     puts(return_to_continue);
  1026.     so_exit();
  1027.  
  1028. #if ONLY_RETURN
  1029.     while ((c = getc()) != '\n' && c != '\r')
  1030.         bell();
  1031. #else
  1032.     c = getc();
  1033.     if (c != '\n' && c != '\r' && c != ' ')
  1034.     {
  1035.         buf[0] = c;
  1036.         first_cmd = buf;
  1037.     }
  1038. #endif
  1039.  
  1040.     if (strlen(s) > sc_width)
  1041.         repaint();
  1042. }
  1043.  
  1044.     public int
  1045. error_width()
  1046. {
  1047.     /*
  1048.      * Don't use the last position, because some terminals
  1049.      * will scroll if you write in the last char of the last line.
  1050.      */
  1051.     return (sc_width - 
  1052.         (sizeof(return_to_continue) + so_width + se_width + 1));
  1053. }
  1054. SHAR_EOF
  1055. fi
  1056. if test -f 'pager_patch.c'
  1057. then
  1058.     echo shar: "will not over-write existing file 'pager_patch.c'"
  1059. else
  1060. cat << \SHAR_EOF > 'pager_patch.c'
  1061. /*
  1062.  * Special interface that checks for the environment variable PAGER.  If
  1063.  * present, the program specified is executed, otherwise OLD_PAGER_NEW_LOCATION
  1064.  * (specified below).  This program should replace /usr/ucb/more (or whatever
  1065.  * your default pager is) and more should be moved to OLD_PAGER_NEW_LOCATION.
  1066.  * This is essentially a fix for all the programs which *should* check for the
  1067.  * environment variable PAGER, but don't - hopefully it will be obsoleted as
  1068.  * old programs are update to check for PAGER so we can loose the overhead of
  1069.  * reexecuting even this small program ...
  1070.  *
  1071.  * Casey Leedom (lll-crg.arpa!csustan!casey) - 5/29/86
  1072.  */
  1073.  
  1074. #ifndef OLD_PAGER_NEW_LOCATION
  1075. #    define    OLD_PAGER_NEW_LOCATION    "/usr/ucb/More"
  1076. #endif !OLD_PAGER_NEW_LOCATION
  1077.  
  1078. void
  1079. main(argc, argv)
  1080.     int    argc;
  1081.     char    **argv;
  1082. {
  1083.     char    *pager, *getenv();
  1084.  
  1085.     if (!(pager = getenv("PAGER")))
  1086.         pager = OLD_PAGER_NEW_LOCATION;
  1087.     (void) execv(pager, argv);
  1088. }
  1089. SHAR_EOF
  1090. fi
  1091. if test -f 'position.c'
  1092. then
  1093.     echo shar: "will not over-write existing file 'position.c'"
  1094. else
  1095. cat << \SHAR_EOF > 'position.c'
  1096. /*
  1097.  * Routines dealing with the "position" table.
  1098.  * This is a table which tells the position (in the input file) of the
  1099.  * first char on each currently displayed line.
  1100.  *
  1101.  * {{ The position table is scrolled by moving all the entries.
  1102.  *    Would be better to have a circular table 
  1103.  *    and just change a couple of pointers. }}
  1104.  */
  1105.  
  1106. #include "less.h"
  1107. #include "position.h"
  1108.  
  1109. #define    NPOS    100        /* {{ sc_height must be less than NPOS }} */
  1110. static POSITION table[NPOS];    /* The position table */
  1111.  
  1112. extern int sc_width, sc_height;
  1113.  
  1114. /*
  1115.  * Return the position of one of:
  1116.  *    the top (first) line on the screen
  1117.  *    the second line on the screen
  1118.  *    the bottom line on the screen
  1119.  *    the line after the bottom line on the screen
  1120.  */
  1121.     public POSITION
  1122. position(where)
  1123.     int where;
  1124. {
  1125.     switch (where)
  1126.     {
  1127.     case BOTTOM:
  1128.         where = sc_height - 2;
  1129.         break;
  1130.     case BOTTOM_PLUS_ONE:
  1131.         where = sc_height - 1;
  1132.         break;
  1133.     }
  1134.     return (table[where]);
  1135. }
  1136.  
  1137. /*
  1138.  * Add a new file position to the bottom of the position table.
  1139.  */
  1140.     public void
  1141. add_forw_pos(pos)
  1142.     POSITION pos;
  1143. {
  1144.     register int i;
  1145.  
  1146.     /*
  1147.      * Scroll the position table up.
  1148.      */
  1149.     for (i = 1;  i < sc_height;  i++)
  1150.         table[i-1] = table[i];
  1151.     table[sc_height - 1] = pos;
  1152. }
  1153.  
  1154. /*
  1155.  * Add a new file position to the top of the position table.
  1156.  */
  1157.     public void
  1158. add_back_pos(pos)
  1159.     POSITION pos;
  1160. {
  1161.     register int i;
  1162.  
  1163.     /*
  1164.      * Scroll the position table down.
  1165.      */
  1166.     for (i = sc_height - 1;  i > 0;  i--)
  1167.         table[i] = table[i-1];
  1168.     table[0] = pos;
  1169. }
  1170.  
  1171. /*
  1172.  * Initialize the position table, done whenever we clear the screen.
  1173.  */
  1174.     public void
  1175. pos_clear()
  1176. {
  1177.     register int i;
  1178.  
  1179.     for (i = 0;  i < sc_height;  i++)
  1180.         table[i] = NULL_POSITION;
  1181. }
  1182.  
  1183. /*
  1184.  * See if the byte at a specified position is currently on the screen.
  1185.  * Check the position table to see if the position falls within its range.
  1186.  * Return the position table entry if found, -1 if not.
  1187.  */
  1188.     public int
  1189. onscreen(pos)
  1190.     POSITION pos;
  1191. {
  1192.     register int i;
  1193.  
  1194.     if (pos < table[0])
  1195.         return (-1);
  1196.     for (i = 1;  i < sc_height;  i++)
  1197.         if (pos < table[i])
  1198.             return (i-1);
  1199.     return (-1);
  1200. }
  1201. SHAR_EOF
  1202. fi
  1203. if test -f 'position.h'
  1204. then
  1205.     echo shar: "will not over-write existing file 'position.h'"
  1206. else
  1207. cat << \SHAR_EOF > 'position.h'
  1208. /*
  1209.  * Include file for interfacing to position.c modules.
  1210.  */
  1211. #define    TOP        0
  1212. #define    TOP_PLUS_ONE    1
  1213. #define    BOTTOM        -1
  1214. #define    BOTTOM_PLUS_ONE    -2
  1215. SHAR_EOF
  1216. fi
  1217. if test -f 'prim.c'
  1218. then
  1219.     echo shar: "will not over-write existing file 'prim.c'"
  1220. else
  1221. cat << \SHAR_EOF > 'prim.c'
  1222. /*
  1223.  * Primitives for displaying the file on the screen.
  1224.  */
  1225.  
  1226. #include "less.h"
  1227. #include "position.h"
  1228.  
  1229. public int hit_eof;    /* Keeps track of how many times we hit end of file */
  1230.  
  1231. extern int quiet;
  1232. extern int top_search;
  1233. extern int top_scroll;
  1234. extern int back_scroll;
  1235. extern int sc_width, sc_height;
  1236. extern int sigs;
  1237. extern char *line;
  1238. extern char *first_cmd;
  1239.  
  1240. /*
  1241.  * Sound the bell to indicate he is trying to move past end of file.
  1242.  */
  1243.     static void
  1244. eof_bell()
  1245. {
  1246.     if (quiet == NOT_QUIET)
  1247.         bell();
  1248.     else
  1249.         vbell();
  1250. }
  1251.  
  1252. /*
  1253.  * Check to see if the end of file is currently "displayed".
  1254.  */
  1255.     static void
  1256. eof_check()
  1257. {
  1258.     POSITION pos;
  1259.  
  1260.     /*
  1261.      * If the bottom line is empty, we are at EOF.
  1262.      * If the bottom line ends at the file length,
  1263.      * we must be just at EOF.
  1264.      */
  1265.     pos = position(BOTTOM_PLUS_ONE);
  1266.     if (pos == NULL_POSITION || pos == ch_length())
  1267.         hit_eof++;
  1268. }
  1269.  
  1270. /*
  1271.  * Display n lines, scrolling forward, 
  1272.  * starting at position pos in the input file.
  1273.  * "force" means display the n lines even if we hit end of file.
  1274.  * "only_last" means display only the last screenful if n > screen size.
  1275.  */
  1276.     static void
  1277. forw(n, pos, force, only_last)
  1278.     register int n;
  1279.     POSITION pos;
  1280.     int force;
  1281.     int only_last;
  1282. {
  1283.     int eof = 0;
  1284.     int nlines = 0;
  1285.     int repaint_flag;
  1286.  
  1287.     /*
  1288.      * repaint_flag tells us not to display anything till the end, 
  1289.      * then just repaint the entire screen.
  1290.      */
  1291.     repaint_flag = (only_last && n > sc_height-1);
  1292.  
  1293.     if (!repaint_flag)
  1294.     {
  1295.         if (top_scroll && n >= sc_height - 1)
  1296.         {
  1297.             /*
  1298.              * Start a new screen.
  1299.              * {{ This is not really desirable if we happen
  1300.              *    to hit eof in the middle of this screen,
  1301.              *    but we don't know if that will happen now. }}
  1302.              */
  1303.             clear();
  1304.             home();
  1305.             force = 1;
  1306.         } else
  1307.         {
  1308.             lower_left();
  1309.             clear_eol();
  1310.         }
  1311.  
  1312.         if (pos != position(BOTTOM_PLUS_ONE))
  1313.         {
  1314.             /*
  1315.              * This is not contiguous with what is
  1316.              * currently displayed.  Clear the screen image 
  1317.              * (position table) and start a new screen.
  1318.              */
  1319.             pos_clear();
  1320.             add_forw_pos(pos);
  1321.             force = 1;
  1322.             if (top_scroll)
  1323.             {
  1324.                 clear();
  1325.                 home();
  1326.             } else
  1327.             {
  1328.                 puts("...skipping...\n");
  1329.             }
  1330.         }
  1331.     }
  1332.  
  1333.     while (--n >= 0)
  1334.     {
  1335.         /*
  1336.          * Read the next line of input.
  1337.          */
  1338.         pos = forw_line(pos);
  1339.         if (pos == NULL_POSITION)
  1340.         {
  1341.             /*
  1342.              * End of file: stop here unless the top line 
  1343.              * is still empty, or "force" is true.
  1344.              */
  1345.             eof = 1;
  1346.             if (!force && position(TOP) != NULL_POSITION)
  1347.                 break;
  1348.             line = NULL;
  1349.         }
  1350.         /*
  1351.          * Add the position of the next line to the position table.
  1352.          * Display the current line on the screen.
  1353.          */
  1354.         add_forw_pos(pos);
  1355.         nlines++;
  1356.         if (!repaint_flag)
  1357.             put_line();
  1358.     }
  1359.  
  1360.     if (eof)
  1361.         hit_eof++;
  1362.     else
  1363.         eof_check();
  1364.     if (nlines == 0)
  1365.         eof_bell();
  1366.     else if (repaint_flag)
  1367.         repaint();
  1368. }
  1369.  
  1370. /*
  1371.  * Display n lines, scrolling backward.
  1372.  */
  1373.     static void
  1374. back(n, pos, force, only_last)
  1375.     register int n;
  1376.     POSITION pos;
  1377.     int force;
  1378.     int only_last;
  1379. {
  1380.     int nlines = 0;
  1381.     int repaint_flag;
  1382.  
  1383.     repaint_flag = (n > back_scroll || (only_last && n > sc_height-1));
  1384.     hit_eof = 0;
  1385.     while (--n >= 0)
  1386.     {
  1387.         /*
  1388.          * Get the previous line of input.
  1389.          */
  1390.         pos = back_line(pos);
  1391.         if (pos == NULL_POSITION)
  1392.         {
  1393.             /*
  1394.              * Beginning of file: stop here unless "force" is true.
  1395.              */
  1396.             if (!force)
  1397.                 break;
  1398.             line = NULL;
  1399.         }
  1400.         /*
  1401.          * Add the position of the previous line to the position table.
  1402.          * Display the line on the screen.
  1403.          */
  1404.         add_back_pos(pos);
  1405.         nlines++;
  1406.         if (!repaint_flag)
  1407.         {
  1408.             home();
  1409.             add_line();
  1410.             put_line();
  1411.         }
  1412.     }
  1413.  
  1414.     eof_check();
  1415.     if (nlines == 0)
  1416.         eof_bell();
  1417.     else if (repaint_flag)
  1418.         repaint();
  1419. }
  1420.  
  1421. /*
  1422.  * Display n more lines, forward.
  1423.  * Start just after the line currently displayed at the bottom of the screen.
  1424.  */
  1425.     public void
  1426. forward(n, only_last)
  1427.     int n;
  1428.     int only_last;
  1429. {
  1430.     POSITION pos;
  1431.  
  1432.     pos = position(BOTTOM_PLUS_ONE);
  1433.     if (pos == NULL_POSITION)
  1434.     {
  1435.         eof_bell();
  1436.         hit_eof++;
  1437.         return;
  1438.     }
  1439.     forw(n, pos, 0, only_last);
  1440. }
  1441.  
  1442. /*
  1443.  * Display n more lines, backward.
  1444.  * Start just before the line currently displayed at the top of the screen.
  1445.  */
  1446.     public void
  1447. backward(n, only_last)
  1448.     int n;
  1449.     int only_last;
  1450. {
  1451.     POSITION pos;
  1452.  
  1453.     pos = position(TOP);
  1454.     if (pos == NULL_POSITION)
  1455.     {
  1456.         /* 
  1457.          * This will almost never happen,
  1458.          * because the top line is almost never empty. 
  1459.          */
  1460.         eof_bell();
  1461.         return;   
  1462.     }
  1463.     back(n, pos, 0, only_last);
  1464. }
  1465.  
  1466. /*
  1467.  * Repaint the screen, starting from a specified position.
  1468.  */
  1469.     static void
  1470. prepaint(pos)    
  1471.     POSITION pos;
  1472. {
  1473.     hit_eof = 0;
  1474.     forw(sc_height-1, pos, 0, 0);
  1475. }
  1476.  
  1477. /*
  1478.  * Repaint the screen.
  1479.  */
  1480.     public void
  1481. repaint()
  1482. {
  1483.     /*
  1484.      * Start at the line currently at the top of the screen
  1485.      * and redisplay the screen.
  1486.      */
  1487.     prepaint(position(TOP));
  1488. }
  1489.  
  1490. /*
  1491.  * Jump to the end of the file.
  1492.  * It is more convenient to paint the screen backward,
  1493.  * from the end of the file toward the beginning.
  1494.  */
  1495.     public void
  1496. jump_forw()
  1497. {
  1498.     POSITION pos;
  1499.  
  1500.     if (ch_end_seek())
  1501.     {
  1502.         error("Cannot seek to end of file");
  1503.         return;
  1504.     }
  1505.     pos = ch_tell();
  1506.     clear();
  1507.     pos_clear();
  1508.     add_back_pos(pos);
  1509.     back(sc_height - 1, pos, 0, 0);
  1510. }
  1511.  
  1512. /*
  1513.  * Jump to line n in the file.
  1514.  */
  1515.     public void
  1516. jump_back(n)
  1517.     register int n;
  1518. {
  1519.     register int c;
  1520.  
  1521.     /*
  1522.      * This is done the slow way, by starting at the beginning
  1523.      * of the file and counting newlines.
  1524.      */
  1525.     if (ch_seek((POSITION)0))
  1526.     {
  1527.         /* 
  1528.          * Probably a pipe with beginning of file no longer buffered. 
  1529.          */
  1530.         error("Cannot get to beginning of file");
  1531.         return;
  1532.     }
  1533.  
  1534.     /*
  1535.      * Start counting lines.
  1536.      */
  1537.     while (--n > 0)
  1538.     {
  1539.         while ((c = ch_forw_get()) != '\n')
  1540.             if (c == EOF)
  1541.             {
  1542.                 error("File is not that long");
  1543.                 /* {{ Maybe tell him how long it is? }} */
  1544.                 return;
  1545.             }
  1546.     }
  1547.  
  1548.     /*
  1549.      * Finally found the place to start.
  1550.      * Clear and redisplay the screen from there.
  1551.      *
  1552.      * {{ We *could* figure out if the new position is 
  1553.      *    close enough to just scroll there without clearing
  1554.      *    the screen, but it's not worth it. }}
  1555.      */
  1556.     prepaint(ch_tell());
  1557. }
  1558.  
  1559. /*
  1560.  * Jump to a specified percentage into the file.
  1561.  * This is a poor compensation for not being able to
  1562.  * quickly jump to a specific line number.
  1563.  */
  1564.     public void
  1565. jump_percent(percent)
  1566.     int percent;
  1567. {
  1568.     POSITION pos, len;
  1569.  
  1570.     /*
  1571.      * Determine the position in the file
  1572.      * (the specified percentage of the file's length).
  1573.      */
  1574.     if ((len = ch_length()) == NULL_POSITION)
  1575.     {
  1576.         error("Don't know length of file");
  1577.         return;
  1578.     }
  1579.     pos = (percent * len) / 100;
  1580.     jump_loc(pos);
  1581. }
  1582.  
  1583.     public void
  1584. jump_loc(pos)
  1585.     POSITION pos;
  1586. {
  1587.     register int c;
  1588.     register int nline;
  1589.     POSITION tpos;
  1590.  
  1591.     /*
  1592.      * See if the desired line is BEFORE the currently
  1593.      * displayed screen.  If so, see if it is close enough 
  1594.      * to scroll backwards to it.
  1595.      */
  1596.     tpos = position(TOP);
  1597.     if (pos < tpos)
  1598.     {
  1599.         for (nline = 1;  nline <= back_scroll;  nline++)
  1600.         {
  1601.             tpos = back_line(tpos);
  1602.             if (tpos == NULL_POSITION || tpos <= pos)
  1603.             {
  1604.                 back(nline, position(TOP), 1, 0);
  1605.                 return;
  1606.             }
  1607.         }
  1608.     } else if ((nline = onscreen(pos)) >= 0)
  1609.     {
  1610.         /*
  1611.          * The line is currently displayed.  
  1612.          * Just scroll there.
  1613.          */
  1614.         forw(nline, position(BOTTOM_PLUS_ONE), 1, 0);
  1615.         return;
  1616.     }
  1617.  
  1618.     /*
  1619.      * Line is not on screen.
  1620.      * Back up to the beginning of the current line.
  1621.      */
  1622.     if (ch_seek(pos))
  1623.     {
  1624.         error("Cannot seek to that position");
  1625.         return;
  1626.     }
  1627.     while ((c = ch_back_get()) != '\n' && c != EOF)
  1628.         ;
  1629.     if (c == '\n')
  1630.         (void) ch_forw_get();
  1631.  
  1632.     /*
  1633.      * Clear and paint the screen.
  1634.      */
  1635.     prepaint(ch_tell());
  1636. }
  1637.  
  1638. /*
  1639.  * The table of marks.
  1640.  * A mark is simply a position in the file.
  1641.  */
  1642. static POSITION marks[26];
  1643.  
  1644. /*
  1645.  * Initialize the mark table to show no marks are set.
  1646.  */
  1647.     public void
  1648. init_mark()
  1649. {
  1650.     int i;
  1651.  
  1652.     for (i = 0;  i < 26;  i++)
  1653.         marks[i] = NULL_POSITION;
  1654. }
  1655.  
  1656. /*
  1657.  * See if a mark letter is valid (between a and z).
  1658.  */
  1659.     static int
  1660. badmark(c)
  1661.     int c;
  1662. {
  1663.     if (c < 'a' || c > 'z')
  1664.     {
  1665.         error("Choose a letter between 'a' and 'z'");
  1666.         return (1);
  1667.     }
  1668.     return (0);
  1669. }
  1670.  
  1671. /*
  1672.  * Set a mark.
  1673.  */
  1674.     public void
  1675. setmark(c)
  1676.     int c;
  1677. {
  1678.     if (badmark(c))
  1679.         return;
  1680.     marks[c-'a'] = position(TOP);
  1681. }
  1682.  
  1683. /*
  1684.  * Go to a previously set mark.
  1685.  */
  1686.     public void
  1687. gomark(c)
  1688.     int c;
  1689. {
  1690.     POSITION pos;
  1691.  
  1692.     if (badmark(c))
  1693.         return;
  1694.     if ((pos = marks[c-'a']) == NULL_POSITION)
  1695.         error("mark not set");
  1696.     else
  1697.         jump_loc(pos);
  1698. }
  1699.  
  1700. /*
  1701.  * Search for the n-th occurence of a specified pattern, 
  1702.  * either forward (direction == '/'), or backwards (direction == '?').
  1703.  */
  1704.     public void
  1705. search(direction, pattern, n)
  1706.     int direction;
  1707.     char *pattern;
  1708.     register int n;
  1709. {
  1710.     register int search_forward = (direction == '/');
  1711.     POSITION pos, linepos;
  1712.  
  1713. #if RECOMP
  1714.     char *re_comp();
  1715.     char *errmsg;
  1716.  
  1717.     /*
  1718.      * (re_comp handles a null pattern internally, 
  1719.      *  so there is no need to check for a null pattern here.)
  1720.      */
  1721.     if ((errmsg = re_comp(pattern)) != NULL)
  1722.     {
  1723.         error(errmsg);
  1724.         return;
  1725.     }
  1726. #else
  1727. #if REGCMP
  1728.     char *regcmp();
  1729.     static char *cpattern = NULL;
  1730.  
  1731.     if (pattern == NULL || *pattern == '\0')
  1732.     {
  1733.         /*
  1734.          * A null pattern means use the previous pattern.
  1735.          * The compiled previous pattern is in cpattern, so just use it.
  1736.          */
  1737.         if (cpattern == NULL)
  1738.         {
  1739.             error("No previous regular expression");
  1740.             return;
  1741.         }
  1742.     } else
  1743.     {
  1744.         /*
  1745.          * Otherwise compile the given pattern.
  1746.          */
  1747.         char *s;
  1748.         if ((s = regcmp(pattern, 0)) == NULL)
  1749.         {
  1750.             error("Invalid pattern");
  1751.             return;
  1752.         }
  1753.         if (cpattern != NULL)
  1754.             free(cpattern);
  1755.         cpattern = s;
  1756.     }
  1757. #else
  1758.     static char lpbuf[100];
  1759.     static char *last_pattern = NULL;
  1760.  
  1761.     if (pattern == NULL || *pattern == '\0')
  1762.     {
  1763.         /*
  1764.          * Null pattern means use the previous pattern.
  1765.          */
  1766.         if (last_pattern == NULL)
  1767.         {
  1768.             error("No previous regular expression");
  1769.             return;
  1770.         }
  1771.         pattern = last_pattern;
  1772.     } else
  1773.     {
  1774.         strcpy(lpbuf, pattern);
  1775.         last_pattern = lpbuf;
  1776.     }
  1777. #endif
  1778. #endif
  1779.  
  1780.     /*
  1781.      * Figure out where to start the search.
  1782.      */
  1783.  
  1784.     if (position(TOP) == NULL_POSITION)
  1785.     {
  1786.         /*
  1787.          * Nothing is currently displayed.
  1788.          * Start at the beginning of the file.
  1789.          * (This case is mainly for first_cmd searches,
  1790.          * for example, "+/xyz" on the command line.)
  1791.          */
  1792.         pos = (POSITION)0;
  1793.     } else if (!search_forward)
  1794.     {
  1795.         /*
  1796.          * Backward search: start just before the top line
  1797.          * displayed on the screen.
  1798.          */
  1799.         pos = position(TOP);
  1800.     } else if (top_search)
  1801.     {
  1802.         /*
  1803.          * Forward search and "start from top".
  1804.          * Start at the second line displayed on the screen.
  1805.          */
  1806.         pos = position(TOP_PLUS_ONE);
  1807.     } else
  1808.     {
  1809.         /*
  1810.          * Forward search but don't "start from top".
  1811.          * Start just after the bottom line displayed on the screen.
  1812.          */
  1813.         pos = position(BOTTOM_PLUS_ONE);
  1814.     }
  1815.  
  1816.     if (pos == NULL_POSITION)
  1817.     {
  1818.         /*
  1819.          * Can't find anyplace to start searching from.
  1820.          */
  1821.         error("Nothing to search");
  1822.         return;
  1823.     }
  1824.  
  1825.     for (;;)
  1826.     {
  1827.         /*
  1828.          * Get lines until we find a matching one or 
  1829.          * until we hit end-of-file (or beginning-of-file 
  1830.          * if we're going backwards).
  1831.          */
  1832.         if (sigs)
  1833.             /*
  1834.              * A signal aborts the search.
  1835.              */
  1836.             return;
  1837.  
  1838.         if (search_forward)
  1839.         {
  1840.             /*
  1841.              * Read the next line, and save the 
  1842.              * starting position of that line in linepos.
  1843.              */
  1844.             linepos = pos;
  1845.             pos = forw_raw_line(pos);
  1846.         } else
  1847.         {
  1848.             /*
  1849.              * Read the previous line and save the
  1850.              * starting position of that line in linepos.
  1851.              */
  1852.             pos = back_raw_line(pos);
  1853.             linepos = pos;
  1854.         }
  1855.  
  1856.         if (pos == NULL_POSITION)
  1857.         {
  1858.             /*
  1859.              * We hit EOF/BOF without a match.
  1860.              */
  1861.             error("Pattern not found");
  1862.             return;
  1863.         }
  1864.  
  1865.         /*
  1866.          * Test the next line to see if we have a match.
  1867.          * This is done in a variety of ways, depending
  1868.          * on what pattern matching functions are available.
  1869.          */
  1870. #if REGCMP
  1871.         if ( (regex(cpattern, line) != NULL)
  1872. #else
  1873. #if RECOMP
  1874.         if ( (re_exec(line) == 1)
  1875. #else
  1876.         if ( (match(pattern, line))
  1877. #endif
  1878. #endif
  1879.                 && (--n <= 0) )
  1880.             /*
  1881.              * Found the matching line.
  1882.              */
  1883.             break;
  1884.     }
  1885.     jump_loc(linepos);
  1886. }
  1887.  
  1888. #if (!REGCMP) && (!RECOMP)
  1889. /*
  1890.  * We have neither regcmp() nor re_comp().
  1891.  * We use this function to do simple pattern matching.
  1892.  * It supports no metacharacters like *, etc.
  1893.  */
  1894.     static int
  1895. match(pattern, buf)
  1896.     char *pattern, *buf;
  1897. {
  1898.     register char *pp, *lp;
  1899.  
  1900.     for ( ;  *buf != '\0';  buf++)
  1901.     {
  1902.         for (pp = pattern, lp = buf;  *pp == *lp;  pp++, lp++)
  1903.             if (*pp == '\0' || *lp == '\0')
  1904.                 break;
  1905.         if (*pp == '\0')
  1906.             return (1);
  1907.     }
  1908.     return (0);
  1909. }
  1910. #endif
  1911. SHAR_EOF
  1912. fi
  1913. if test -f 'prompt.c'
  1914. then
  1915.     echo shar: "will not over-write existing file 'prompt.c'"
  1916. else
  1917. cat << \SHAR_EOF > 'prompt.c'
  1918. /*
  1919.  * Prompting and other messages.
  1920.  * There are three flavors of prompts, SHORT, MEDIUM and LONG,
  1921.  * selected by the -m/-M options.
  1922.  * A prompt is either a colon or a message composed of various
  1923.  * pieces, such as the name of the file being viewed, the percentage
  1924.  * into the file, etc.
  1925.  */
  1926.  
  1927. #include "less.h"
  1928. #include "position.h"
  1929.  
  1930. extern int pr_type;
  1931. extern int ispipe;
  1932. extern int hit_eof;
  1933. extern int new_file;
  1934. extern int sc_width;
  1935. extern char current_file[];
  1936. extern int ac;
  1937. extern char **av;
  1938. extern int curr_ac;
  1939.  
  1940. static char message[500];
  1941.  
  1942. /*
  1943.  * Append the name of the current file (to the message buffer).
  1944.  */
  1945.     static void
  1946. ap_filename()
  1947. {
  1948.     if (!ispipe)
  1949.         sprintf(message + strlen(message), 
  1950.             "%s", current_file);
  1951. }
  1952.  
  1953. /*
  1954.  * Append the "file N of M" message.
  1955.  */
  1956.     static void
  1957. ap_of()
  1958. {
  1959.     if (ac > 1)
  1960.         sprintf(message + strlen(message), 
  1961.             " (file %d of %d)", curr_ac+1, ac);
  1962. }
  1963.  
  1964. /*
  1965.  * Append the byte offset into the current file.
  1966.  */
  1967.     static void
  1968. ap_byte()
  1969. {
  1970.     POSITION pos, len;
  1971.  
  1972.     pos = position(BOTTOM_PLUS_ONE);
  1973.     if (pos != NULL_POSITION)
  1974.     {
  1975.         sprintf(message + strlen(message), 
  1976.             " byte %ld", pos);
  1977.         len = ch_length();
  1978.         if (len > 0)
  1979.             sprintf(message + strlen(message), 
  1980.                 "/%ld", len);
  1981.     }
  1982. }
  1983.  
  1984. /*
  1985.  * Append the percentage into the current file.
  1986.  * If we cannot find the percentage and must_print is true,
  1987.  * the use the byte offset.
  1988.  */
  1989.     static void
  1990. ap_percent(must_print)
  1991. {
  1992.     POSITION pos,len;
  1993.  
  1994.     pos = position(BOTTOM_PLUS_ONE);
  1995.     len = ch_length();
  1996.     if (len > 0 && pos != NULL_POSITION)
  1997.         sprintf(message + strlen(message),
  1998.             " (%ld%%)", (100 * pos) / len);
  1999.     else if (must_print)
  2000.         ap_byte();
  2001. }
  2002.  
  2003. /*
  2004.  * Append the end-of-file message.
  2005.  */
  2006.     static void
  2007. ap_eof()
  2008. {
  2009.     strcat(message, " END");
  2010.     if (curr_ac + 1 < ac)
  2011.         sprintf(message + strlen(message),
  2012.             " - Next: %s", av[curr_ac+1]);
  2013. }
  2014.  
  2015. /*
  2016.  * Return a message suitable for printing by the "=" command.
  2017.  */
  2018.     public char *
  2019. eq_message()
  2020. {
  2021.     message[0] = '\0';
  2022.     ap_filename();
  2023.     ap_of();
  2024.     ap_byte();
  2025.     ap_percent(0);
  2026.     /*
  2027.      * Truncate to the screen width.
  2028.      * {{ This isn't very nice. }}
  2029.      */
  2030.     message[error_width()] = '\0';
  2031.     return (message);
  2032. }
  2033.  
  2034. /*
  2035.  * Return a prompt.
  2036.  * This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
  2037.  * If we can't come up with an appropriate prompt, return NULL
  2038.  * and the caller will prompt with a colon.
  2039.  */
  2040.     public char *
  2041. pr_string()
  2042. {
  2043.     message[0] = '\0';
  2044.     switch (pr_type)
  2045.     {
  2046.     case PR_SHORT:
  2047.         if (new_file)
  2048.         {
  2049.             ap_filename();
  2050.             ap_of();
  2051.         }
  2052.         if (hit_eof)
  2053.             ap_eof();
  2054.         break;
  2055.     case PR_MEDIUM:
  2056.         if (new_file)
  2057.         {
  2058.             ap_filename();
  2059.             ap_of();
  2060.         }
  2061.         if (hit_eof)
  2062.             ap_eof();
  2063.         else
  2064.             ap_percent(1);
  2065.         break;
  2066.     case PR_LONG:
  2067.         ap_filename();
  2068.         if (new_file)
  2069.             ap_of();
  2070.         ap_byte();
  2071.         if (hit_eof)
  2072.             ap_eof();
  2073.         else
  2074.             ap_percent(0);
  2075.         break;
  2076.     }
  2077.     new_file = 0;
  2078.     if (message[0] == '\0')
  2079.         return (NULL);
  2080.     /*
  2081.      * Truncate to the screen width.
  2082.      * {{ This isn't very nice. }}
  2083.      */
  2084.     message[sc_width-2] = '\0';
  2085.     return (message);
  2086. }
  2087. SHAR_EOF
  2088. fi
  2089. if test -f 'screen.c'
  2090. then
  2091.     echo shar: "will not over-write existing file 'screen.c'"
  2092. else
  2093. cat << \SHAR_EOF > 'screen.c'
  2094. /*
  2095.  * Routines which deal with the characteristics of the terminal.
  2096.  * Uses termcap to be as terminal-independent as possible.
  2097.  *
  2098.  * {{ Someday this should be rewritten to use curses. }}
  2099.  */
  2100.  
  2101. #include "less.h"
  2102. #if XENIX
  2103. #include <sys/types.h>
  2104. #include <sys/ioctl.h>
  2105. #endif
  2106.  
  2107. #if TERMIO
  2108. #include <termio.h>
  2109. #else
  2110. #include <sgtty.h>
  2111. #endif
  2112.  
  2113. /*
  2114.  * Strings passed to tputs() to do various terminal functions.
  2115.  */
  2116. static char
  2117.     *sc_pad,        /* Pad string */
  2118.     *sc_home,        /* Cursor home */
  2119.     *sc_addline,        /* Add line, scroll down following lines */
  2120.     *sc_lower_left,        /* Cursor to last line, first column */
  2121.     *sc_move,        /* General cursor positioning */
  2122.     *sc_clear,        /* Clear screen */
  2123.     *sc_eol_clear,        /* Clear to end of line */
  2124.     *sc_s_in,        /* Enter standout (highlighted) mode */
  2125.     *sc_s_out,        /* Exit standout mode */
  2126.     *sc_u_in,        /* Enter underline mode */
  2127.     *sc_u_out,        /* Exit underline mode */
  2128.     *sc_b_in,        /* Enter bold mode */
  2129.     *sc_b_out,        /* Exit bold mode */
  2130.     *sc_visual_bell,    /* Visual bell (flash screen) sequence */
  2131.     *sc_backspace,        /* Backspace cursor */
  2132.     *sc_init,        /* Startup terminal initialization */
  2133.     *sc_deinit;        /* Exit terminal de-intialization */
  2134. static int dumb;
  2135. static int hard;
  2136.  
  2137. public int auto_wrap;        /* Terminal does \r\n when write past margin */
  2138. public int ignaw;        /* Terminal ignores \n immediately after wrap */
  2139. public int erase_char, kill_char; /* The user's erase and line-kill chars */
  2140. public int sc_width, sc_height;    /* Height & width of screen */
  2141. public int sc_window = -1;    /* window size for forward and backward */
  2142. public int bo_width, be_width;    /* Printing width of boldface sequences */
  2143. public int ul_width, ue_width;    /* Printing width of underline sequences */
  2144. public int so_width, se_width;    /* Printing width of standout sequences */
  2145.  
  2146. /*
  2147.  * These two variables are sometimes defined in,
  2148.  * and needed by, the termcap library.
  2149.  * It may be necessary on some systems to declare them extern here.
  2150.  */
  2151. /*extern*/ short ospeed;    /* Terminal output baud rate */
  2152. /*extern*/ char P    ;        /* Pad character */
  2153.  
  2154. extern int quiet;        /* If VERY_QUIET, use visual bell for bell */
  2155. extern int know_dumb;        /* Don't complain about a dumb terminal */
  2156. extern int back_scroll;
  2157. char *tgetstr();
  2158. char *tgoto();
  2159.  
  2160. /*
  2161.  * Change terminal to "raw mode", or restore to "normal" mode.
  2162.  * "Raw mode" means 
  2163.  *    1. An outstanding read will complete on receipt of a single keystroke.
  2164.  *    2. Input is not echoed.  
  2165.  *    3. On output, \n is mapped to \r\n.
  2166.  *    4. \t is NOT be expanded into spaces.
  2167.  *    5. Signal-causing characters such as ctrl-C (interrupt),
  2168.  *       etc. are NOT disabled.
  2169.  * It doesn't matter whether an input \n is mapped to \r, or vice versa.
  2170.  */
  2171.     public void
  2172. raw_mode(on)
  2173.     int on;
  2174. {
  2175. #if TERMIO
  2176.     struct termio s;
  2177.     static struct termio save_term;
  2178.  
  2179.     if (on)
  2180.     {
  2181.         /*
  2182.          * Get terminal modes.
  2183.          */
  2184.         ioctl(2, TCGETA, &s);
  2185.  
  2186.         /*
  2187.          * Save modes and set certain variables dependent on modes.
  2188.          */
  2189.         save_term = s;
  2190.         ospeed = s.c_cflag & CBAUD;
  2191.         erase_char = s.c_cc[VERASE];
  2192.         kill_char = s.c_cc[VKILL];
  2193.  
  2194.         /*
  2195.          * Set the modes to the way we want them.
  2196.          */
  2197.         s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  2198.         s.c_oflag |=  (OPOST|ONLCR|TAB3);
  2199.         s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
  2200.         s.c_cc[VMIN] = 1;
  2201.         s.c_cc[VTIME] = 0;
  2202.     } else
  2203.     {
  2204.         /*
  2205.          * Restore saved modes.
  2206.          */
  2207.         s = save_term;
  2208.     }
  2209.     ioctl(2, TCSETAW, &s);
  2210. #else
  2211.     struct sgttyb s;
  2212.     static struct sgttyb save_term;
  2213.  
  2214.     if (on)
  2215.     {
  2216.         /*
  2217.          * Get terminal modes.
  2218.          */
  2219.         ioctl(2, TIOCGETP, &s);
  2220.  
  2221.         /*
  2222.          * Save modes and set certain variables dependent on modes.
  2223.          */
  2224.         save_term = s;
  2225.         ospeed = s.sg_ospeed;
  2226.         erase_char = s.sg_erase;
  2227.         kill_char = s.sg_kill;
  2228.  
  2229.         /*
  2230.          * Set the modes to the way we want them.
  2231.          */
  2232.         s.sg_flags |= CBREAK;
  2233.         s.sg_flags &= ~(ECHO|XTABS);
  2234.     } else
  2235.     {
  2236.         /*
  2237.          * Restore saved modes.
  2238.          */
  2239.         s = save_term;
  2240.     }
  2241.     ioctl(2, TIOCSETN, &s);
  2242. #endif
  2243. }
  2244.  
  2245. static int couldnt = 0;
  2246.  
  2247.     static void
  2248. cannot(s)
  2249.     char *s;
  2250. {
  2251.     if (know_dumb)
  2252.         /* 
  2253.          * He knows he has a dumb terminal, so don't tell him. 
  2254.          */
  2255.         return;
  2256.  
  2257.     printf("WARNING: terminal cannot \"%s\"\n", s);
  2258.     couldnt = 1;
  2259. }
  2260.  
  2261. /*
  2262.  * Get terminal capabilities via termcap.
  2263.  */
  2264.     public void
  2265. get_term()
  2266. {
  2267.     char termbuf[1024];
  2268.     char *sp;
  2269.     static char sbuf[150];
  2270.  
  2271.     char *getenv();
  2272.  
  2273.     /*
  2274.      * Find out what kind of terminal this is.
  2275.      */
  2276.     if (tgetent(termbuf, getenv("TERM")) <= 0)
  2277.         dumb = 1;
  2278.  
  2279.     /*
  2280.      * Get size of the screen.
  2281.      */
  2282.     if (dumb || (sc_height = tgetnum("li")) < 0 || tgetflag("hc"))
  2283.     {
  2284.         /* Oh no, this is a hardcopy terminal. */
  2285.         hard = 1;
  2286.         sc_height = 24;
  2287.     }
  2288.     /*
  2289.      * This is terrible - the following if "knows" that it is being
  2290.      * executed *after* command line and environment options have
  2291.      * already been parsed.  Should it be executed in the main program
  2292.      * instead?
  2293.      */
  2294.     if ((sc_window <= 0) || (sc_window >= sc_height))
  2295.         sc_window = sc_height-1;
  2296.     if (dumb || (sc_width = tgetnum("co")) < 0)
  2297.         sc_width = 80;
  2298.  
  2299.     auto_wrap = tgetflag("am");
  2300.     ignaw = tgetflag("xn");
  2301.  
  2302.     /*
  2303.      * Assumes termcap variable "sg" is the printing width of
  2304.      * the standout sequence, the end standout sequence,
  2305.      * the underline sequence, the end underline sequence,
  2306.      * the boldface sequence, and the end boldface sequence.
  2307.      */
  2308.     if ((so_width = tgetnum("sg")) < 0)
  2309.         so_width = 0;
  2310.     be_width = bo_width = ue_width = ul_width = se_width = so_width;
  2311.  
  2312.     /*
  2313.      * Get various string-valued capabilities.
  2314.      */
  2315.     sp = sbuf;
  2316.  
  2317.     sc_pad = (dumb) ? NULL : tgetstr("pc", &sp);
  2318.     if (sc_pad != NULL)
  2319.         PC = *sc_pad;
  2320.  
  2321.     sc_init = (dumb) ? NULL : tgetstr("ti", &sp);
  2322.     if (sc_init == NULL)
  2323.         sc_init = "";
  2324.  
  2325.     sc_deinit= (dumb) ? NULL : tgetstr("te", &sp);
  2326.     if (sc_deinit == NULL)
  2327.         sc_deinit = "";
  2328.  
  2329.     sc_eol_clear = (dumb) ? NULL : tgetstr("ce", &sp);
  2330.     if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')
  2331.     {
  2332.         cannot("clear to end of line");
  2333.         sc_eol_clear = "";
  2334.     }
  2335.  
  2336.     sc_clear = (dumb) ? NULL : tgetstr("cl", &sp);
  2337.     if (hard || sc_clear == NULL || *sc_clear == '\0')
  2338.     {
  2339.         cannot("clear screen");
  2340.         sc_clear = "\n\n";
  2341.     }
  2342.  
  2343.     sc_move = (dumb) ? NULL : tgetstr("cm", &sp);
  2344.     if (hard || sc_move == NULL || *sc_move == '\0')
  2345.     {
  2346.         /*
  2347.          * This is not an error here, because we don't 
  2348.          * always need sc_move.
  2349.          * We need it only if we don't have home or lower-left.
  2350.          */
  2351.         sc_move = "";
  2352.     }
  2353.  
  2354.     sc_s_in = (dumb) ? NULL : tgetstr("so", &sp);
  2355.     if (hard || sc_s_in == NULL)
  2356.         sc_s_in = "";
  2357.  
  2358.     sc_s_out = (dumb) ? NULL : tgetstr("se", &sp);
  2359.     if (hard || sc_s_out == NULL)
  2360.         sc_s_out = "";
  2361.  
  2362.     sc_u_in = (dumb) ? NULL : tgetstr("us", &sp);
  2363.     if (hard || sc_u_in == NULL)
  2364.         sc_u_in = sc_s_in;
  2365.  
  2366.     sc_u_out = (dumb) ? NULL : tgetstr("ue", &sp);
  2367.     if (hard || sc_u_out == NULL)
  2368.         sc_u_out = sc_s_out;
  2369.  
  2370.     sc_b_in = (dumb) ? NULL : tgetstr("md", &sp);
  2371.     if (hard || sc_b_in == NULL)
  2372.     {
  2373.         sc_b_in = sc_s_in;
  2374.         sc_b_out = sc_s_out;
  2375.     } else
  2376.     {
  2377.         sc_b_out = (dumb) ? NULL : tgetstr("me", &sp);
  2378.         if (hard || sc_b_out == NULL)
  2379.             sc_b_out = "";
  2380.     }
  2381.  
  2382.     sc_visual_bell = (dumb) ? NULL : tgetstr("vb", &sp);
  2383.     if (hard || sc_visual_bell == NULL)
  2384.         sc_visual_bell = "";
  2385.  
  2386.     sc_home = (dumb) ? NULL : tgetstr("ho", &sp);
  2387.     if (hard || sc_home == NULL || *sc_home == '\0')
  2388.     {
  2389.         if (*sc_move == '\0')
  2390.         {
  2391.             cannot("home cursor");
  2392.             /*
  2393.              * This last resort for sc_home is supposed to
  2394.              * be an up-arrow suggesting moving to the 
  2395.              * top of the "virtual screen". (The one in
  2396.              * your imagination as you try to use this on
  2397.              * a hard copy terminal.)
  2398.              */
  2399.             sc_home = "|\b^";        
  2400.         } else
  2401.         {
  2402.             /* 
  2403.              * No "home" string,
  2404.              * but we can use "move(0,0)".
  2405.              */
  2406.             strcpy(sp, tgoto(sc_move, 0, 0));
  2407.             sc_home = sp;
  2408.             sp += strlen(sp) + 1;
  2409.         }
  2410.     }
  2411.  
  2412.     sc_lower_left = (dumb) ? NULL : tgetstr("ll", &sp);
  2413.     if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')
  2414.     {
  2415.         if (*sc_move == '\0')
  2416.         {
  2417.             cannot("move cursor to lower left of screen");
  2418.             sc_lower_left = "\r";
  2419.         } else
  2420.         {
  2421.             /*
  2422.              * No "lower-left" string, 
  2423.              * but we can use "move(0,last-line)".
  2424.              */
  2425.             strcpy(sp, tgoto(sc_move, 0, sc_height-1));
  2426.             sc_lower_left = sp;
  2427.             sp += strlen(sp) + 1;
  2428.         }
  2429.     }
  2430.  
  2431.     /*
  2432.      * To add a line at top of screen and scroll the display down,
  2433.      * we use "al" (add line) or "sr" (scroll reverse).
  2434.      */
  2435.     if (dumb)
  2436.         sc_addline = NULL;
  2437.     else if ((sc_addline = tgetstr("al", &sp)) == NULL || 
  2438.          *sc_addline == '\0')
  2439.         sc_addline = tgetstr("sr", &sp);
  2440.  
  2441.     if (hard || sc_addline == NULL || *sc_addline == '\0')
  2442.     {
  2443.         cannot("scroll backwards");
  2444.         sc_addline = "";
  2445.         /* Force repaint on any backward movement */
  2446.         back_scroll = 0;
  2447.     }
  2448.  
  2449.     if (dumb || tgetflag("bs"))
  2450.         sc_backspace = "\b";
  2451.     else
  2452.     {
  2453.         sc_backspace = tgetstr("bc", &sp);
  2454.         if (sc_backspace == NULL || *sc_backspace == '\0')
  2455.             sc_backspace = "\b";
  2456.     }
  2457.  
  2458.     if (couldnt)
  2459.         /* Give him time to read all the "cannot" messages. */
  2460.         error("");
  2461. }
  2462.  
  2463.  
  2464. /*
  2465.  * Below are the functions which perform all the 
  2466.  * terminal-specific screen manipulation.
  2467.  */
  2468.  
  2469.  
  2470. /*
  2471.  * Initialize terminal
  2472.  */
  2473.     public void
  2474. init()
  2475. {
  2476.     tputs(sc_init, sc_height, putc);
  2477. }
  2478.  
  2479. /*
  2480.  * Deinitialize terminal
  2481.  */
  2482.     public void
  2483. deinit()
  2484. {
  2485.     tputs(sc_deinit, sc_height, putc);
  2486. }
  2487.  
  2488. /*
  2489.  * Home cursor (move to upper left corner of screen).
  2490.  */
  2491.     public void
  2492. home()
  2493. {
  2494.     tputs(sc_home, 1, putc);
  2495. }
  2496.  
  2497. /*
  2498.  * Add a blank line (called with cursor at home).
  2499.  * Should scroll the display down.
  2500.  */
  2501.     public void
  2502. add_line()
  2503. {
  2504.     tputs(sc_addline, sc_height, putc);
  2505. }
  2506.  
  2507. /*
  2508.  * Move cursor to lower left corner of screen.
  2509.  */
  2510.     public void
  2511. lower_left()
  2512. {
  2513.     tputs(sc_lower_left, 1, putc);
  2514. }
  2515.  
  2516. /*
  2517.  * Ring the terminal bell.
  2518.  */
  2519.     public void
  2520. bell()
  2521. {
  2522.     if (quiet == VERY_QUIET)
  2523.         vbell();
  2524.     else
  2525.         putc('\7');
  2526. }
  2527.  
  2528. /*
  2529.  * Output the "visual bell", if there is one.
  2530.  */
  2531.     public void
  2532. vbell()
  2533. {
  2534.     if (*sc_visual_bell == '\0')
  2535.         return;
  2536.     tputs(sc_visual_bell, sc_height, putc);
  2537. }
  2538.  
  2539. /*
  2540.  * Clear the screen.
  2541.  */
  2542.     public void
  2543. clear()
  2544. {
  2545.     tputs(sc_clear, sc_height, putc);
  2546. }
  2547.  
  2548. /*
  2549.  * Clear from the cursor to the end of the cursor's line.
  2550.  * {{ This must not move the cursor. }}
  2551.  */
  2552.     public void
  2553. clear_eol()
  2554. {
  2555.     tputs(sc_eol_clear, 1, putc);
  2556. }
  2557.  
  2558. /*
  2559.  * Begin "standout"
  2560.  */
  2561.     public void
  2562. so_enter()
  2563. {
  2564.     tputs(sc_s_in, 1, putc);
  2565. }
  2566.  
  2567. /*
  2568.  * End "standout".
  2569.  */
  2570.     public void
  2571. so_exit()
  2572. {
  2573.     tputs(sc_s_out, 1, putc);
  2574. }
  2575.  
  2576. /*
  2577.  * Begin "underline" (hopefully real underlining, 
  2578.  * otherwise whatever the terminal provides).
  2579.  */
  2580.     public void
  2581. ul_enter()
  2582. {
  2583.     tputs(sc_u_in, 1, putc);
  2584. }
  2585.  
  2586. /*
  2587.  * End "underline".
  2588.  */
  2589.     public void
  2590. ul_exit()
  2591. {
  2592.     tputs(sc_u_out, 1, putc);
  2593. }
  2594.  
  2595. /*
  2596.  * Begin "bold"
  2597.  */
  2598.     public void
  2599. bo_enter()
  2600. {
  2601.     tputs(sc_b_in, 1, putc);
  2602. }
  2603.  
  2604. /*
  2605.  * End "bold".
  2606.  */
  2607.     public void
  2608. bo_exit()
  2609. {
  2610.     tputs(sc_b_out, 1, putc);
  2611. }
  2612.  
  2613. /*
  2614.  * Erase the character to the left of the cursor 
  2615.  * and move the cursor left.
  2616.  */
  2617.     public void
  2618. backspace()
  2619. {
  2620.     /* 
  2621.      * Try to erase the previous character by overstriking with a space.
  2622.      */
  2623.     tputs(sc_backspace, 1, putc);
  2624.     putc(' ');
  2625.     tputs(sc_backspace, 1, putc);
  2626. }
  2627.  
  2628. /*
  2629.  * Output a plain backspace, without erasing the previous char.
  2630.  */
  2631.     public void
  2632. putbs()
  2633. {
  2634.     tputs(sc_backspace, 1, putc);
  2635. }
  2636. SHAR_EOF
  2637. fi
  2638. if test -f 'signal.c'
  2639. then
  2640.     echo shar: "will not over-write existing file 'signal.c'"
  2641. else
  2642. cat << \SHAR_EOF > 'signal.c'
  2643. /*
  2644.  * Routines dealing with signals.
  2645.  *
  2646.  * A signal usually merely causes a bit to be set in the "signals" word.
  2647.  * At some convenient time, the mainline code checks to see if any
  2648.  * signals need processing by calling psignal().
  2649.  * An exception is made if we are reading from the keyboard when the
  2650.  * signal is received.  Some operating systems will simply call the
  2651.  * signal handler and NOT return from the read (with EINTR).
  2652.  * To handle this case, we service the interrupt directly from
  2653.  * the handler if we are reading from the keyboard.
  2654.  */
  2655.  
  2656. #include "less.h"
  2657. #include <signal.h>
  2658. #include <setjmp.h>
  2659.  
  2660. /*
  2661.  * The type of signal handler functions.
  2662.  * Usually int, although it should be void.
  2663.  */
  2664. typedef    int        HANDLER;
  2665.  
  2666. /*
  2667.  * "sigs" contains bits indicating signals which need to be processed.
  2668.  */
  2669. public int sigs;
  2670. #define    S_INTERRUPT    01
  2671. #ifdef SIGTSTP
  2672. #define    S_STOP        02
  2673. #endif
  2674.  
  2675. extern int reading;
  2676. extern char *first_cmd;
  2677. extern jmp_buf main_loop;
  2678.  
  2679. /*
  2680.  * Interrupt signal handler.
  2681.  */
  2682.     static HANDLER
  2683. interrupt()
  2684. {
  2685.     SIGNAL(SIGINT, interrupt);
  2686.     sigs |= S_INTERRUPT;
  2687.     if (reading)
  2688.         psignals();
  2689. }
  2690.  
  2691. #ifdef SIGTSTP
  2692. /*
  2693.  * "Stop" (^Z) signal handler.
  2694.  */
  2695.     static HANDLER
  2696. stop()
  2697. {
  2698.     SIGNAL(SIGTSTP, stop);
  2699.     sigs |= S_STOP;
  2700.     if (reading)
  2701.         psignals();
  2702. }
  2703. #endif
  2704.  
  2705. /*
  2706.  * Set up the signal handlers.
  2707.  */
  2708.     public void
  2709. init_signals()
  2710. {
  2711.     (void) SIGNAL(SIGINT, interrupt);
  2712. #ifdef SIGTSTP
  2713.     (void) SIGNAL(SIGTSTP, stop);
  2714. #endif
  2715. }
  2716.  
  2717. /*
  2718.  * Process any signals we have recieved.
  2719.  * A received signal cause a bit to be set in "sigs".
  2720.  */
  2721.     public void 
  2722. psignals()
  2723. {
  2724.     register int tsignals;
  2725.  
  2726.     tsignals = sigs;
  2727.     sigs = 0;
  2728.     if (tsignals == 0)
  2729.         return;
  2730.  
  2731.     dropout();        /* Discard any buffered output */
  2732.  
  2733. #ifdef SIGTSTP
  2734.     if (tsignals & S_STOP)
  2735.     {
  2736.         /*
  2737.          * Clean up the terminal.
  2738.          */
  2739. #ifdef SIGTTOU
  2740.         SIGNAL(SIGTTOU, SIG_IGN);
  2741. #endif
  2742.         lower_left();
  2743.         clear_eol();
  2744.         flush();
  2745.         raw_mode(0);
  2746. #ifdef SIGTTOU
  2747.         SIGNAL(SIGTTOU, SIG_DFL);
  2748. #endif
  2749.         SIGNAL(SIGTSTP, SIG_DFL);
  2750. #if SIGSETMASK
  2751.         /*
  2752.          * This system will not allow us to send a 
  2753.          * stop signal (SIGTSTP) to ourself
  2754.          * while we are in the signal handler, like maybe now.
  2755.          * (This can be the case if we are reading; see comment above.)
  2756.          * So we ask the silly system for permission to do so.
  2757.          */
  2758.         sigsetmask(0);
  2759. #endif
  2760.         kill(getpid(), SIGTSTP);
  2761.         /*
  2762.          * ... Bye bye. ...
  2763.          * Hopefully we'll be back later and resume here...
  2764.          * Reset the terminal and arrange to repaint the
  2765.          * screen when we get back to the main command loop.
  2766.          */
  2767.         SIGNAL(SIGTSTP, stop);
  2768.         raw_mode(1);
  2769.         first_cmd = "r";
  2770.         longjmp(main_loop, 1);
  2771.     }
  2772. #endif
  2773.     if (tsignals & S_INTERRUPT)
  2774.     {
  2775.         bell();
  2776.         /*
  2777.          * {{ You may wish to replace the bell() with 
  2778.          *    error("Interrupt"); }}
  2779.          */
  2780.     }
  2781.  
  2782.     longjmp(main_loop, 1);
  2783. }
  2784.  
  2785. /*
  2786.  * Pass the specified command to a shell to be executed.
  2787.  * Like plain "system()", but handles resetting terminal modes, etc.
  2788.  */
  2789.     public void
  2790. lsystem(cmd)
  2791.     char *cmd;
  2792. {
  2793.     int inp;
  2794.  
  2795.     /*
  2796.      * Print the command which is to be executed.
  2797.      */
  2798.     lower_left();
  2799.     clear_eol();
  2800.     puts("!");
  2801.     puts(cmd);
  2802.     puts("\n");
  2803.  
  2804.     /*
  2805.      * De-initialize the terminal and take out of raw mode.
  2806.      */
  2807.     deinit();
  2808.     flush();
  2809.     raw_mode(0);
  2810.  
  2811.     /*
  2812.      * Restore signals to their defaults.
  2813.      */
  2814.     SIGNAL(SIGINT, SIG_DFL);
  2815. #ifdef SIGTSTP
  2816.     SIGNAL(SIGTSTP, SIG_DFL);
  2817. #endif
  2818.     /*
  2819.      * Pass the command to the system to be executed.
  2820.      */
  2821.     inp = dup(0);
  2822.     close(0);
  2823.     open("/dev/tty", 0);
  2824.  
  2825.     system(cmd);
  2826.  
  2827.     close(0);
  2828.     dup(inp);
  2829.     close(inp);
  2830.  
  2831.     /*
  2832.      * Reset signals, raw mode, etc.
  2833.      */
  2834.     init_signals();
  2835.     raw_mode(1);
  2836.     init();
  2837. }
  2838. SHAR_EOF
  2839. fi
  2840. if test -f 'ttyin.c'
  2841. then
  2842.     echo shar: "will not over-write existing file 'ttyin.c'"
  2843. else
  2844. cat << \SHAR_EOF > 'ttyin.c'
  2845. /*
  2846.  * Routines dealing with getting input from the keyboard (i.e. from the user).
  2847.  */
  2848.  
  2849. #include "less.h"
  2850.  
  2851. /*
  2852.  * The boolean "reading" is set true or false according to whether
  2853.  * we are currently reading from the keyboard.
  2854.  * This information is used by the signal handling stuff in signal.c.
  2855.  * {{ There are probably some race conditions here
  2856.  *    involving the variable "reading". }}
  2857.  */
  2858. public int reading;
  2859.  
  2860. static int tty;
  2861.  
  2862. /*
  2863.  * Open keyboard for input.
  2864.  * (Just use file descriptor 2.)
  2865.  */
  2866.     public void
  2867. open_getc()
  2868. {
  2869.     tty = 2;
  2870. }
  2871.  
  2872. /*
  2873.  * Get a character from the keyboard.
  2874.  */
  2875.     public int
  2876. getc()
  2877. {
  2878.     char c;
  2879.     int result;
  2880.  
  2881.     reading = 1;
  2882.     do
  2883.     {
  2884.         flush();
  2885.         result = read(tty, &c, 1);
  2886.     } while (result != 1);
  2887.     reading = 0;
  2888.     return (c & 0177);
  2889. }
  2890. SHAR_EOF
  2891. fi
  2892. if test -f 'version.c'
  2893. then
  2894.     echo shar: "will not over-write existing file 'version.c'"
  2895. else
  2896. cat << \SHAR_EOF > 'version.c'
  2897. /*
  2898.  *        less
  2899.  *    Copyright (c) 1984,1985  Mark Nudelman
  2900.  *
  2901.  *    This program may be freely used and/or modified, 
  2902.  *    with the following provisions:
  2903.  *    1. This notice and the above copyright notice must remain intact.
  2904.  *    2. Neither this program, nor any modification of it,
  2905.  *       may not be sold for profit without written consent of the author.
  2906.  *
  2907.  *    -----------------------------------------------------------------
  2908.  *
  2909.  *    This program is a paginator similar to "more", 
  2910.  *    but allows you to move both forward and backward in the file.  
  2911.  *    Commands are based on "more" and "vi".
  2912.  *
  2913.  *    ----------------------- CHANGES ---------------------------------
  2914.  *
  2915.  *        Allowed use on standard input        1/29/84   markn
  2916.  *        Added E, N, P commands            2/1/84    markn
  2917.  *        Added '=' command, 'stop' signal handling    4/17/84   markn
  2918.  *        Added line folding                4/20/84   markn
  2919.  *    v2: Fixed '=' command to use BOTTOM_PLUS_ONE, 
  2920.  *        instead of TOP, added 'p' & 'v' commands    4/27/84   markn
  2921.  *    v3: Added -m and -t options, '-' command    5/3/84    markn
  2922.  *    v4: Added LESS environment variable        5/3/84    markn
  2923.  *    v5: New comments, fixed '-' command slightly    5/3/84    markn
  2924.  *    v6: Added -Q, visual bell            5/15/84   markn
  2925.  *    v7: Fixed jump_back(n) bug: n should count real
  2926.  *        lines, not folded lines.  Also allow number
  2927.  *        on G command.                5/24/84   markn
  2928.  *    v8: Re-do -q and -Q commands            5/30/84   markn
  2929.  *    v9: Added "+<cmd>" argument            9/25/84   markn
  2930.  *    v10: Fixed bug in -b<n> argument processing    10/10/84  markn
  2931.  *    v11: Made error() ring bell if \n not entered.    10/18/84  markn
  2932.  *    -----------------------------------------------------------------
  2933.  *    v12: Reorganized signal handling and made
  2934.  *         portable to 4.2bsd.            2/13/85   mark
  2935.  *    v13: Reword error message for '-' command.    2/16/85   mark
  2936.  *    v14: Added -bf and -bp variants of -b.        2/22/85   mark
  2937.  *    v15: Miscellaneous changes.            2/25/85   mark
  2938.  *    v16: Added -u flag for backspace processing.    3/13/85   mark
  2939.  *    v17: Added j and k commands, 
  2940.  *        changed -t default.            4/13/85   mark
  2941.  *    v18: Rewrote signal handling code.        4/20/85   mark
  2942.  *    v19: Got rid of "verbose" eq_message().        5/2/85    mark
  2943.  *         Made search() scroll in some cases.
  2944.  *    v20: Fixed screen.c ioctls for System V.    5/21/85   mark
  2945.  *    v21: Fixed some first_cmd bugs.            5/23/85   mark
  2946.  *    v22: Added support for no RECOMP nor REGCMP.    5/24/85   mark
  2947.  *    v23: Miscellanous changes and prettying up.    5/25/85   mark
  2948.  *      v24: Added ti,te terminal init & de-init       6/3/85 Mike Kersenbrock
  2949.  *    v25: Added -U flag, standout mode underlining.    6/8/85    mark
  2950.  *    v26: Added -M flag.                6/9/85    mark
  2951.  *         Use underline termcap (us) if it exists.
  2952.  *    v27: Renamed some variables to make unique in    6/15/85   mark
  2953.  *         6 chars.  Minor fix to -m.
  2954.  *    v28: Fixed right margin bug.            6/28/85   mark
  2955.  *    v29: Incorporated M.Rose's changes to signal.c    6/28/85   mark
  2956.  *    v30: Fixed stupid bug in argument processing.    6/29/85   mark
  2957.  *    v31: Added -p flag, changed repaint algorithm.  7/15/85   mark
  2958.  *         Added kludge for magic cookie terminals.
  2959.  *    v32: Added cat_file if output not a tty.    7/16/85   mark
  2960.  *    v33: Added -e flag and EDITOR.            7/23/85   mark
  2961.  *    v34: Added -s flag.                7/26/85   mark
  2962.  *    v35: Rewrote option handling; added option.c.    7/27/85   mark
  2963.  *    v36: Fixed -e flag to work if not last file.    7/29/85   mark
  2964.  *    v37: Added -x flag.                8/10/85   mark
  2965.  *    v38: Changed prompting; created prompt.c.    8/19/85   mark
  2966.  *    v39: (Not -p) does not initially clear screen.    8/24/85   mark
  2967.  *    v40: Added "skipping" indicator in forw().    8/26/85   mark
  2968.  *    v41: ONLY_RETURN, control char commands,    9/17/85   mark
  2969.  *         faster search, other minor fixes.
  2970.  *    v42: Added ++ command line syntax;        9/25/85   mark
  2971.  *         ch_fsize for pipes.
  2972.  *    v43: Added -h flag, changed prim.c algorithms.    10/15/85  mark
  2973.  *    v44: Made END print in all cases of eof;    10/16/85  mark
  2974.  *         ignore SIGTTOU after receiving SIGTSTP.
  2975.  *    v45: Never print backspaces unless -u.        10/16/85  mark
  2976.  *    v46: Backwards scroll in jump_loc.        10/24/85  mark
  2977.  *    v47: Fixed bug in edit(): *first_cmd==0        10/30/85  mark
  2978.  *    v48: Use TIOCSETN instead of TIOCSETP.        11/16/85  mark
  2979.  *         Added marks (m and ' commands).
  2980.  *    -----------------------------------------------------------------
  2981.  */
  2982.  
  2983. char version[] = "@(#) less  version 48";
  2984. SHAR_EOF
  2985. fi
  2986. exit 0
  2987. #    End of shell archive
  2988.  
  2989.  
  2990.